package com.ezjie.ielts.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import com.ezjie.ielts.R;
import com.ezjie.ielts.util.DensityUtil;
import com.ezjie.ielts.util.XChartCalc;

public class ProgressCircle extends View {
	private float mRingBias = 0.15f;
	private float mSectionRatio = 5.0f;
	private RectF mSectionRect = new RectF();
	protected float mSectionHeight;

	protected float mRadius;

	protected int mMaxProgress;
	protected int mProgress;

	protected float mCenterX;
	protected float mCenterY;

	private Paint mPaint;
	private int mColor1;
	private int mInactiveColor;

	{
		mMaxProgress = 100;
		mProgress = 0;

		mPaint = new Paint();
		mPaint.setAntiAlias(true);
		mPaint.setStyle(Paint.Style.FILL);

		mColor1 = Color.parseColor("#ffffae00");
		mInactiveColor = Color.parseColor("#ffdddddd");

		mPaint.setColor(mColor1); // Set default
	}

	public ProgressCircle(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);

		initAttributes(context, attrs);
	}

	public ProgressCircle(Context context, AttributeSet attrs) {
		super(context, attrs);

		initAttributes(context, attrs);
	}

	public ProgressCircle(Context context) {
		super(context);
	}

	private void initAttributes(Context context, AttributeSet attrs) {
		TypedArray attributes = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SeekCircle, 0, 0);
		try {
			// Read and clamp max
			int max = attributes.getInteger(R.styleable.SeekCircle_min, 100);
			mMaxProgress = Math.max(max, 1);

			// Read and clamp progress
			int progress = attributes.getInteger(R.styleable.SeekCircle_progress, 0);
			mProgress = Math.max(Math.min(progress, mMaxProgress), 0);
		} finally {
			attributes.recycle();
		}
	}

	private void updateDimensions(int width, int height) {
		// Update center position
		mCenterX = width / 2f;
		mCenterY = height / 2f;

		// Find shortest dimension
		int diameter = Math.min(width, height);

		float outerRadius = (float) (diameter / 1.5);
		float sectionHeight = (float) (1.5 * outerRadius * mRingBias);
		float sectionWidth = 3 * sectionHeight / mSectionRatio;

		mRadius = outerRadius - sectionHeight * 1.3f;// 设置内圆的半径
		mSectionRect.set(-sectionWidth / 2, -sectionHeight / 2, sectionWidth / 2, sectionHeight / 2);
		mSectionHeight = sectionHeight;
	}

	@Override
	protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		// int width = MeasureSpec.getSize(widthMeasureSpec);
		// int height = MeasureSpec.getSize(heightMeasureSpec);
		//
		// if (width > height)
		// super.onMeasure(heightMeasureSpec, widthMeasureSpec);
		// else
		// super.onMeasure(widthMeasureSpec, widthMeasureSpec);

		// 声明一个临时变量来存储计算出的测量值
		int resultWidth = 0;

		// 获取宽度测量规格中的mode
		int modeWidth = MeasureSpec.getMode(widthMeasureSpec);

		// 获取宽度测量规格中的size
		int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);

		/*
		 * 如果爹心里有数
		 */
		if (modeWidth == MeasureSpec.EXACTLY) {
			// 那么儿子也不要让爹难做就取爹给的大小吧
			resultWidth = sizeWidth;
		}
		/*
		 * 如果爹心里没数
		 */
		else {
			// 那么儿子可要自己看看自己需要多大了
			resultWidth = DensityUtil.dip2px(getContext(), 90);

			/*
			 * 如果爹给儿子的是一个限制值
			 */
			if (modeWidth == MeasureSpec.AT_MOST) {
				// 那么儿子自己的需求就要跟爹的限制比比看谁小要谁
				resultWidth = Math.min(resultWidth, sizeWidth);
			}
		}

		int resultHeight = 0;
		int modeHeight = MeasureSpec.getMode(heightMeasureSpec);
		int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);

		if (modeHeight == MeasureSpec.EXACTLY) {
			resultHeight = sizeHeight;
		} else {
			resultHeight = DensityUtil.dip2px(getContext(), 90);
			if (modeHeight == MeasureSpec.AT_MOST) {
				resultHeight = Math.min(resultHeight, sizeHeight);
			}
		}

		// 设置测量尺寸
		setMeasuredDimension(resultWidth, resultHeight);

		updateDimensions(getWidth(), getHeight());

	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);

		updateDimensions(w, h);
	}

	@Override
	protected void onDraw(Canvas canvas) {

		float arcLeft = mCenterX - mRadius;
		float arcTop = mCenterY - mRadius;
		float arcRight = mCenterX + mRadius;
		float arcBottom = mCenterY + mRadius;
		RectF arcRF0 = new RectF(arcLeft, arcTop, arcRight, arcBottom);

		// 画笔初始化
		Paint PaintArc = new Paint();
		PaintArc.setAntiAlias(true);
		// 位置计算类
		XChartCalc xcalc = new XChartCalc();

		float Percentage = 0.0f;
		float CurrPer = -90.0f;

		for (int i = 0; i < mMaxProgress / 2; ++i) {
			Percentage = (360 - mMaxProgress) / mMaxProgress;
			if (i < mProgress) {
				mPaint.setColor(mColor1);
			} else {
				canvas.scale(1.0f, 1.0f);
				mPaint.setColor(mInactiveColor);
			}
			canvas.drawArc(arcRF0, CurrPer, Percentage - 2, true, mPaint);
			xcalc.CalcArcEndPointXY(mCenterX, mCenterY, mRadius - mRadius / 3 / 3, CurrPer + Percentage / 2);
			CurrPer = CurrPer + Percentage + 1;
		}
		for (int i = mMaxProgress / 2; i < mMaxProgress; ++i) {
			Percentage = (360 - mMaxProgress) / mMaxProgress;

			if (i < mProgress) {
				mPaint.setColor(mColor1);
			} else {
				canvas.scale(1.0f, 1.0f);
				mPaint.setColor(mInactiveColor);
			}
			canvas.drawArc(arcRF0, CurrPer, Percentage - 2, true, mPaint);
			xcalc.CalcArcEndPointXY(mCenterX, mCenterY, mRadius - mRadius / 3 / 3, CurrPer + Percentage / 2);
			CurrPer = CurrPer + Percentage + 1;
		}
		// 画圆心
		PaintArc.setColor(Color.WHITE);
		canvas.drawCircle(mCenterX, mCenterY, (int) (mRadius / 1.2), PaintArc);// 设置外圆半径

		super.onDraw(canvas);
	}

	/**
	 * Get max progress
	 * 
	 * @return Max progress
	 */
	public int getMax() {
		return mMaxProgress;
	}

	/**
	 * Set max progress
	 * 
	 * @param max
	 */
	public void setMax(int max) {
		int newMax = Math.max(max, 1);
		if (newMax != mMaxProgress)
			mMaxProgress = newMax;

		updateProgress(mProgress);
		invalidate();
	}

	/**
	 * Get Progress
	 * 
	 * @return progress
	 */
	public int getProgress() {
		return mProgress;
	}

	/**
	 * Set progress
	 * 
	 * @param progress
	 */
	public void setProgress(int progress) {
		updateProgress(progress);
	}

	/**
	 * Update progress internally. Clamp it to a valid range and invalidate the
	 * view if necessary
	 * 
	 * @param progress
	 * @return true if progress was changed and the view needs an update
	 */
	protected boolean updateProgress(int progress) {
		// Clamp progress
		progress = Math.max(0, Math.min(mMaxProgress, progress));

		if (progress != mProgress) {
			mProgress = progress;
			invalidate();
			return true;
		}

		return false;
	}
}